#include "tapdisk-log.h"
#include "tapdisk-queue.h"
#include "tapdisk-filter.h"
+#include "tapdisk-server.h"
#include "atomicio.h"
#define WARN(_f, _a...) tlog_write(TLOG_WARN, _f, ##_a)
* so that we can concurrently poll on synchronous and async descriptors.
* This is signalled by passing 1 as the io context to io_setup.
*/
-#define REQUEST_ASYNC_FD 1
+#define REQUEST_ASYNC_FD ((io_context_t)1)
static inline void
queue_tiocb(struct tqueue *queue, struct tiocb *tiocb)
return split;
}
+static void tapdisk_tiocb_event(event_id_t id, char mode, void *private);
+
int
tapdisk_init_queue(struct tqueue *queue, int size,
int sync, struct tfilter *filter)
queue->sync = sync;
queue->filter = filter;
- if (sync) {
- /* set up a pipe so we can return
- * a poll fd that won't fire. */
- if (pipe(queue->dummy_pipe))
- return -errno;
- queue->poll_fd = queue->dummy_pipe[0];
- } else {
- queue->aio_ctx = (io_context_t)REQUEST_ASYNC_FD;
- queue->poll_fd = io_setup(size, &queue->aio_ctx);
+ queue->event = -1;
+ queue->aio_ctx = NULL;
- if (queue->poll_fd < 0) {
- if (queue->poll_fd == -EAGAIN)
+ if (!size)
+ return 0;
+
+ if (!sync) {
+ queue->aio_ctx = REQUEST_ASYNC_FD;
+ queue->poll_fd = io_setup(size, &queue->aio_ctx);
+ err = queue->poll_fd;
+ if (err < 0) {
+ if (err == -EAGAIN)
DPRINTF("Couldn't setup AIO context. If you "
"are trying to concurrently use a "
"large number of blktap-based disks, "
"support. This is probably because "
"your kernel does not have the "
"aio-poll patch applied.\n");
- return queue->poll_fd;
+ queue->aio_ctx = NULL;
+ goto fail;
}
+
+ queue->event =
+ tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
+ queue->poll_fd, 0,
+ tapdisk_tiocb_event,
+ queue);
+ err = queue->event;
+ if (err < 0)
+ goto fail;
+
}
err = -ENOMEM;
void
tapdisk_free_queue(struct tqueue *queue)
{
- if (queue->sync) {
- close(queue->dummy_pipe[0]);
- close(queue->dummy_pipe[1]);
- } else
+ if (queue->event >= 0) {
+ tapdisk_server_unregister_event(queue->event);
+ queue->event = -1;
+ }
+
+ if (queue->aio_ctx) {
io_destroy(queue->aio_ctx);
+ queue->aio_ctx = NULL;
+ }
free(queue->iocbs);
+ queue->iocbs = NULL;
+
free(queue->aio_events);
+ queue->aio_events = NULL;
+
opio_free(&queue->opioctx);
}
return submitted;
}
-int
+static void
tapdisk_complete_tiocbs(struct tqueue *queue)
{
int i, ret, split;
}
queue_deferred_tiocbs(queue);
+}
- return split;
+static void
+tapdisk_tiocb_event(event_id_t id, char mode, void *private)
+{
+ struct tqueue *queue = private;
+ tapdisk_complete_tiocbs(queue);
}
/*
#include <libaio.h>
#include "io-optimize.h"
+#include "scheduler.h"
struct tiocb;
struct tfilter;
int sync;
int poll_fd;
+ event_id_t event;
io_context_t aio_ctx;
struct opioctx opioctx;
- int dummy_pipe[2];
int queued;
struct iocb **iocbs;
void tapdisk_queue_tiocb(struct tqueue *, struct tiocb *);
int tapdisk_submit_tiocbs(struct tqueue *);
int tapdisk_submit_all_tiocbs(struct tqueue *);
-int tapdisk_complete_tiocbs(struct tqueue *);
int tapdisk_cancel_tiocbs(struct tqueue *);
int tapdisk_cancel_all_tiocbs(struct tqueue *);
void tapdisk_prep_tiocb(struct tiocb *, int, int, char *, size_t,
tapdisk_ipc_write_error(&vbd->ipc, message);
}
-static void
-tapdisk_server_aio_queue_event(event_id_t id, char mode, void *private)
-{
- tapdisk_complete_tiocbs(&server.aio_queue);
-}
-
-static void
-tapdisk_server_free_aio_queue(void)
-{
- tapdisk_server_unregister_event(server.aio_queue_event_id);
- tapdisk_free_queue(&server.aio_queue);
-}
-
static int
tapdisk_server_init_ipc(const char *read, const char *write)
{
}
static int
-tapdisk_server_initialize_aio_queue(void)
+tapdisk_server_init_aio(void)
{
- int err;
- event_id_t id;
-
- err = tapdisk_init_queue(&server.aio_queue,
- TAPDISK_TIOCBS, 0, NULL);
- if (err)
- return err;
-
- id = tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
- server.aio_queue.poll_fd, 0,
- tapdisk_server_aio_queue_event,
- NULL);
- if (id < 0) {
- tapdisk_free_queue(&server.aio_queue);
- return id;
- }
-
- server.aio_queue_event_id = id;
+ return tapdisk_init_queue(&server.aio_queue, TAPDISK_TIOCBS, 0, NULL);
+}
- return 0;
+static void
+tapdisk_server_close_aio(void)
+{
+ tapdisk_free_queue(&server.aio_queue);
}
static void
tapdisk_server_close(void)
{
- tapdisk_server_free_aio_queue();
+ tapdisk_server_close_aio();
tapdisk_server_close_ipc();
}
if (err)
goto fail;
- err = tapdisk_server_initialize_aio_queue();
+ err = tapdisk_server_init_aio();
if (err)
goto fail;